from django.db import models
from django.core.urlresolvers import reverse
import datetime

from django.http import Http404, HttpResponseForbidden

from xBlog.MailReminder import send_email_async
from .IpInfo import get_ip_info, ip_protect
from django.db.utils import IntegrityError


def get_default_archive():
    return datetime.datetime.now().strftime('%Y-%m')


# Create your models here.
class Tag(models.Model):
    tag_name = models.CharField(max_length=50)

    def __str__(self):
        return self.tag_name


class Catagory(models.Model):
    catagory_name = models.CharField(max_length=100)

    def __str__(self):
        return self.catagory_name


class Archive(models.Model):
    archive_name = models.CharField(max_length=50, default=get_default_archive)

    def __str__(self):
        return self.archive_name


class Article(models.Model):
    title = models.CharField(max_length=100)
    catagory = models.ForeignKey(Catagory, null=True)
    tags = models.ManyToManyField(Tag)
    archive = models.ForeignKey(Archive, null=True)
    date_time = models.DateTimeField(auto_now_add=True)
    content = models.TextField(blank=True, null=True)
    visit_count = models.IntegerField(default=0)

    def visit(self):
        self.visit_count += 1
        self.save()

    def change(self, title, catagory, archive, tags, content):
        if title and catagory and archive and tags and content:
            self.title = title
            self.catagory = catagory
            self.archive = archive
            self.tags = tags
            self.content = content
            self.save()
        else:
            raise ValueError('Params cannot be NULL')

    def get_absolute_url(self):
        path = reverse('detail', kwargs={'article_id': self.id})
        return path

    def __str__(self):
        return self.title

    class Meta:
        ordering = ['-date_time']


class Link(models.Model):
    title = models.CharField(max_length=100)
    link = models.CharField(max_length=150)

    def __str__(self):
        return self.title


class Visitor(models.Model):
    nickname = models.CharField(max_length=100)
    url = models.CharField(max_length=150, null=True)
    email = models.CharField(max_length=150, null=True)
    ip_address = models.CharField(max_length=50, unique=True)
    date_time = models.DateTimeField(auto_now_add=True)
    city = models.CharField(max_length=100)

    @staticmethod
    def get_visitor(ip, abort403=False):
        try:
            visitor = Visitor.objects.get(ip_address=ip)
        except Visitor.DoesNotExist:
            if abort403:
                raise
            visitor = Visitor()
            ip_location = get_ip_info(ip)
            city = ip_location['city'] or ip_location['country']
            city = city[:city.index('市')] if '市' in city else city
            visitor.nickname = '网友'
            visitor.ip_address = ip
            visitor.city = city
            try:
                visitor.save()
            except IntegrityError:
                visitor = Visitor.objects.get(ip_address=ip)
        except Visitor.MultipleObjectsReturned:
            visitors = Visitor.objects.filter(ip_address=ip)
            for v in visitors[1:]:
                v.delete()
            visitor = visitors[0]

        return visitor

    def __str__(self):
        return self.ip_address


class ReadRecord(models.Model):
    visitor = models.ForeignKey(Visitor)
    article = models.ForeignKey(Article)
    date_time = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.visitor.ip_address + '@' + self.date_time.strftime('%Y-%m-%d %H:%M:%S')


class Comment(models.Model):
    article_id = models.ForeignKey(Article)
    visitor = models.ForeignKey(Visitor)
    content = models.TextField(blank=False)
    reply_to_who_id = models.ForeignKey('self', null=True, blank=True)
    reply_to = models.CharField(max_length=150, null=True, blank=True)
    submit_time = models.DateTimeField(auto_now_add=True)
    comment_id = models.IntegerField(default=1)

    def submit(self, reply_to_who_id):
        if reply_to_who_id != 'null':
            try:
                reply_to_comment = Comment.objects.select_related().get(pk=reply_to_who_id)
            except Comment.DoesNotExist:
                raise Http404

            reply_to = '回复 #' + str(reply_to_comment.comment_id) + ' ' + reply_to_comment.visitor.nickname + ip_protect(
                reply_to_comment.visitor.ip_address) + '[' + reply_to_comment.visitor.city + ']'

            self.reply_to_who_id = reply_to_comment
            self.reply_to = reply_to
        else:
            reply_to = ''
        self.save()

        if self.reply_to_who_id and self.reply_to_who_id.visitor.email:
            send_email_async(self.visitor, self.reply_to_who_id.visitor, self.reply_to_who_id.article_id,
                             self.comment_id)

        return reply_to

    def save(self, force_insert=False, force_update=False, using=None,
             update_fields=None):
        comments = Comment.objects.filter(article_id=self.article_id).order_by('-comment_id')
        cid = 1
        if comments:
            cid = comments[0].comment_id + 1

        self.comment_id = cid
        super(Comment, self).save()

    def __str__(self):
        return self.article_id.title + '@' + self.visitor.nickname + '@' + self.submit_time.strftime('%Y-%m-%d %H:%M')


class BrowseRecord(models.Model):
    date_time = models.DateTimeField(auto_now_add=True)
    visitor = models.ForeignKey(Visitor)

    def __str__(self):
        return self.visitor.ip_address + '@' + self.date_time.strftime('%Y-%m-%d %H:%M:%S')


class Files(models.Model):
    filename = models.CharField(max_length=100)
    file_id = models.CharField(max_length=50)
    url = models.CharField(max_length=100)

    def __str__(self):
        return self.filename


class Thinkpage_city(models.Model):
    class Meta:
        db_table = 'thinkpage_cities'

    city_id = models.CharField(max_length=12, primary_key=True, unique=True, null=False, db_column='city_id')
    city_name = models.CharField(max_length=25, null=False, db_column='city_name')
    city_pinyin = models.CharField(max_length=30, null=False, db_column='city_pinyin')

    @classmethod
    def get_id_by_name(cls, city_name):
        try:
            city_id = cls.objects.filter(city_name=city_name)[0].city_id
        except IndexError:
            return 'error'
        else:
            return city_id

    def __str__(self):
        return self.city_name
